package com.wh1200.xmlless.test.model

import com.wh1200.mybatis.xmlless.annotations.*
import com.baomidou.mybatisplus.annotation.TableField
import com.baomidou.mybatisplus.annotation.TableLogic
import jakarta.persistence.*
import org.springframework.data.annotation.CreatedBy
import org.springframework.data.annotation.CreatedDate
import org.springframework.data.annotation.LastModifiedBy
import org.springframework.data.annotation.LastModifiedDate
import java.time.LocalDate
import java.time.LocalDateTime
import kotlin.jvm.Transient

/**
 *
 * @author 吴昊
 * @since 0.0.4
 */
@Entity
@Table(name = "t_student")
class Student(
    var name: String = "",
    var age: Int = 0,
    /** 年级 */
    var grade: Int = 0,
    var birthday: LocalDate? = null
) {

  @Count(
      targetTable = "t_score",
      targetColumn = "student_id",
      countColumn = "id"
  )
  @Transient
  var count: Int = 0

  @JsonMappingProperty
  var data: List<StudentDetail> = listOf()


  @CreatedDate
  @FeignProperty(
      targetEntity = com.wh1200.xmlless.test.model.DateConfig::class,
      joinOnTargetProperty = "date_format(date, '%Y-%m-%d')",
      joinOnThisProperty = "date_format(createTime, '%Y-%m-%d')",
      alias = "dateConfig"
  )
  var createTime: LocalDateTime? = null

  @JsonMappingProperty
  var detail: StudentDetail? = null

  @JsonMappingProperty
  var education: List<EducationInfo>? = null
  var email: String? = null

  @JsonMappingProperty
  var favorites: List<String> = listOf()

  @Column(name = "sex")
  @TableField("sex")
  var gender: Int = 1
  var graduated: Boolean = false

  @Id
  @GeneratedValue(generator = "SNOWFLAKE", strategy = GenerationType.AUTO)
  var id: String? = null

  @Column(insertable = false, updatable = false)
  var tenantId: String? = null

  @JsonMappingProperty
  var nickNames: List<String>? = null

  @Handler(com.wh1200.xmlless.test.model.StringTypeHandler::class)
  var phoneNumber: String = ""

  @TableLogic(
      value = "false",
      delval = "true"
  )
  @Column(name = "del_flag")
  var deleted: Boolean = false

  @JoinObject(
      joinOnTargetProperty = "studentId",
      joinOnThisProperty = "id"
  )
  @SelectedProperties(["score", "subjectId", "subject"])
  @JoinColumn(insertable = false, updatable = false)
  var scores: MutableList<com.wh1200.xmlless.test.model.Score>? = null

  var state: com.wh1200.xmlless.test.model.StudentState = com.wh1200.xmlless.test.model.StudentState.Normal

  @CreatedBy
  @FeignProperty(
      targetEntity = com.wh1200.xmlless.test.model.User::class,
      joinOnTargetProperty = "id",
      joinOnThisProperty = "createUserId",
      alias = "createUser"
  )
  var createUserId: Int? = null

  @LastModifiedBy
  @FeignProperty(
      targetEntity = com.wh1200.xmlless.test.model.User::class,
      alias = "updateUser"
  )
  var updateUserId: Int? = null

  @LastModifiedDate
  var updateTime: LocalDateTime? = null

  @PropertyMapping("createUser.name")
  var createUserName: String? = null

  @FeignProperty(
      targetEntity = com.wh1200.xmlless.test.model.School::class,
      alias = "school"
  )
  var schoolId: String? = null


  @PropertyMapping("updateUser.name")
  var updateUserName: String? = null

  @FeignProperty(
      targetEntity = com.wh1200.xmlless.test.model.User::class,
      alias = "u"
  )
  var userId: Int? = null

  @PropertyMapping("u.name")
  var userName: String? = null

  @Version
  var version: Int = 0

  constructor(
      id: String, name: String, phoneNumber: String,
      gender: Int, state: com.wh1200.xmlless.test.model.StudentState = com.wh1200.xmlless.test.model.StudentState.Normal
  ) : this() {
    this.id = id
    this.name = name
    this.phoneNumber = phoneNumber
    this.gender = gender
    this.state = state
  }

  override fun toString(): String {
    return """Student(
      | name=$name,
      | phoneNumber=$phoneNumber,
      | gender=$gender,
      | graduated=$graduated,
      | scores=$scores
      | favorites=$favorites
      | birthday=$birthday
      |)""".trimMargin()
  }

}
